using System.Collections;
using System.Collections.Generic;
using Core.Mgr._Timer;
using DG.Tweening;
using UnityEngine;

namespace Core.Extension
{
    /// <summary>
    /// 对象池单例 TODO 待研究Unity的单例类
    /// </summary>
    public class ObjectPool : Singleton<ObjectPool>
    {
        private Dictionary<string, List<GameObject>> cache = new Dictionary<string, List<GameObject>>();

        /// <summary>
        /// 创建显示对象
        /// </summary>
        /// <returns>The object.</returns>
        /// <param name="key">对象名称</param>
        /// <param name="go">对象的预制件</param>
        /// <param name="parent">父对象</param>
        /// <param name="localPosition">对象的新位置</param>
        public GameObject CreateObject(string key, GameObject go, Transform parent, Vector3 localPosition)
        {
            //返回池中未激活的对象，所有都被激活就返回空，赋值给临时对象
            GameObject tempgo = cache.ContainsKey(key) ? cache[key].Find(p => !p.activeSelf) : null;
            if (tempgo != null) //如果临时对象不为空
            {
                tempgo.transform.localPosition = localPosition; //设置位置
                tempgo.transform.parent = parent;
                tempgo.transform.SetParent(parent); //旋转信息
                tempgo.name = key;
            }
            else //否则，就是空了。（也就是没能从池子里取出对象）
            {
                tempgo = Object.Instantiate(go, parent); //那就根据传入的预设物，生成一个新物体
                tempgo.transform.localPosition = localPosition;
                tempgo.name = key;
                // Debug.Log("key实例化物体数量：" + ++i);
                if (!cache.ContainsKey(key)) //池中没有键
                {
                    cache.Add(key, new List<GameObject>()); //新建一个 列表
                }

                cache[key].Add(tempgo); //给字典中的列表加入/add 临时物体，如果有键就直接添加了
            }

            tempgo.SetActive(true); //并启用临时物体
            return tempgo; //返回
        }


        /// <summary>
        /// 直接回收
        /// </summary>
        /// <param name="go">Go.</param>
        public void CollectObject(GameObject go)
        {
            if (go != null)
            {
                go.SetActive(false);
            }
        }


        /// <summary>
        /// 延迟回收
        /// </summary>
        /// <param name="go">Go.</param>
        /// <param name="delay">Delay.</param>
        public void CollectObject(GameObject go, float delay)
        {
            GameRoot.Ins.StartCoroutine(Collect(go, delay));
        }

        private IEnumerator Collect(GameObject go, float delay)
        {
            yield return new WaitForSeconds(delay);
            CollectObject(go);
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <returns>The clear.</returns>
        /// <param name="key">Key.</param>
        public void Clear(string key)
        {
            if (cache.ContainsKey(key))
            {
                //Destroy当中所有的对象
                for (int i = 0; i < cache[key].Count; i++)
                {
                    Object.Destroy(cache[key][i]);
                }

                //清除键当中的所有值
                //cache[key].Clear();
                //清除这个键（键值一起清除）
                cache.Remove(key);
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <returns>The clear.</returns>
        /// <param name="key">Key.</param>
        /// <param name="isFadeOut">是否渐隐后在消失</param>
        public void Clear(string key, bool isFadeOut)
        {
            if (!isFadeOut)
            {
                Clear(key);
                return;
            }

            if (cache.ContainsKey(key))
            {
                //Destroy当中所有的对象
                for (int i = 0; i < cache[key].Count; i++)
                {
                    // var i1 = i;
                    if (cache[key][i].TryGetComponent(out SpriteRenderer spriteRenderer))
                        spriteRenderer.DOFade(0, 0.5f);
                }

                int _timer = 0;
                _timer = TimerMgr.StartTimer(() =>
                {
                    TimerMgr.EndTimer(_timer);
                    Clear(key);
                    cache.Remove(key);
                }, 0.6f);
            }
        }


        /// <summary>
        /// 释放所有对象池
        /// </summary>
        public void ClearAll()
        {
            var list = new List<string>(cache.Keys);
            for (int i = 0; i < list.Count; i++)
            {
                Clear(list[i]);
            }
        }
    }
}